home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 113_01 / a15.c < prev    next >
Text File  |  1985-03-09  |  7KB  |  236 lines

  1. /*
  2.     HEADER:        CUG113;
  3.     TITLE:        1802 Cross-Assembler (BDS C Version);
  4.     FILENAME:    A15.C;
  5.     VERSION:    1.2;
  6.     DATE:        07/22/1985;
  7.  
  8.     DESCRIPTION:    "This program lets you use your CP/M-80-based computer
  9.             to assemble code for the RCA 1802, 1804, 1805, 1805A,
  10.             1806, AND 1806A microprocessors.  The program is
  11.             written in BDS C for the best possible performance on
  12.             8-bit machines.  All assembler features are supported
  13.             except relocation, linkage, listing control, and
  14.             macros.";
  15.  
  16.     KEYWORDS:    Software Development, Assemblers, Cross-Assemblers,
  17.             RCA, CDP1802, CDP1805A;
  18.  
  19.     SEE-ALSO:    CUG149, 1805A Cross-Assembler (Portable);
  20.  
  21.     SYSTEM:        CP/M-80;
  22.     COMPILERS:    BDS C;
  23.  
  24.     WARNINGS:    "This package is specifically tailored to CP/M-80
  25.             machines and the rather non-standard, but high-
  26.             performance BDS C compiler.  For other environments,
  27.             use the portable version of this package on CUG149.";
  28.  
  29.     AUTHORS:    William C. Colley III;
  30. */
  31.  
  32. /*
  33.     1805A Cross-Assembler  v 1.2
  34.  
  35.     Copyright (c) 1980, 82, 83, 85 William C. Colley, III.
  36.  
  37.     July 1982 -- Adapted from my 1802 cross-assembler.  WCC3.
  38.  
  39.     Vers 1.0 -- March 1983 -- Added 1805A opcodes to the 1805 set.  WCC3.
  40.  
  41.     Vers 1.1 -- March 1983 -- Added CPU pseudo-op to combine 1802 and 1805A
  42.             cross-assemblers into a single program.  WCC3.
  43.  
  44.     Vers 1.2 -- June 1985 -- Fixed IF block nesting mechanism bug and bug
  45.             in 1805A SCAL opcode.  WCC3.
  46.  
  47. File:    a15.c
  48.  
  49. It all begins here.
  50. */
  51.  
  52. /*  Get globals:  */
  53.  
  54. #include "a15.h"
  55.  
  56. /*  The assembler starts here.  */
  57.  
  58. main(argc,argv)
  59. int argc;
  60. char *argv[];
  61. {
  62.     int n, m;
  63.  
  64.     puts("1805A/1802 Cross-Assembler Version 1.2\n");
  65.     puts("Copyright (c) 1980,82,83,85  William C. Colley III\n");
  66.     curdrive = bdos(GETDISK);  setfiles(argc,argv);
  67.     sympoint = symtbl;            /*  Initialize symbol table.    */
  68.     symend = symtbl[SYMBOLS].symname;
  69.     setmem(sympoint,(SYMBOLS * (SYMLEN + 2)),'\0');
  70.     setmem(linbuf,SYMLEN,' ');        /*  Install initial symbols.    */
  71.     linbuf[0] = 'R';  linbuf[1] = '0';
  72.     for (n = 0; n < 16; n++) {
  73.     addsym(linbuf);  sympoint->symvalu = n;
  74.     if ((linbuf[1] += 1) == ('9' + 1)) linbuf[1] = 'A';
  75.     }
  76.     ifstack[ifsp = 0] = ON;        /*  Initialize if stack.    */
  77.     hxbytes = 0;  flshhbf(0);        /*  Initialize hex generator.    */
  78.     pc = errcount = 0;  pass = 1;  extend = DEFEXT;
  79.     puts("\nEntering Pass 1.\n");
  80.  
  81.     while (pass != 3) {        /*  The actual assembly starts here.    */
  82.     errcode = ' ';
  83.     if (!getlin()) {
  84.         strcpy(linbuf,"\tEND\t\t;You forgot this!\n");
  85.         linptr = linbuf;  markerr('*');  ifstack[ifsp] = ON;
  86.     }
  87.     asmline();            /*  Get binary from line.    */
  88.     if (pass > 1) {
  89.         lineout();            /*  In pass 2, list line.    */
  90.         hexout();            /*  In pass 2, build hex file.    */
  91.     }
  92.     pc += nbytes;
  93.     if (pass == 0) {    /*  This indicates end of pass 1.    */
  94.         pass = 2;  rewind(source);
  95.  
  96.             /*  Mark symbols as not for direct addressing.    */
  97.  
  98.         for (sympoint = symtbl; sympoint < symend; sympoint++)
  99.         sympoint->symname[0] |= 0x80;
  100.  
  101.         ifsp = pc = errcount = 0;  extend = DEFEXT;
  102.  
  103.                     /*  Unmark pre-defined symbols.    */
  104.  
  105.         setmem(linbuf,SYMLEN,' ');  linbuf[0] = 'R';  linbuf[1] = '0';
  106.         for (n = 0; n < 16; n++) {
  107.         slookup(linbuf);  sympoint->symname[0] &= 0x7f;
  108.         if ((linbuf[1] += 1) == ('9' + 1)) linbuf[1] = 'A';
  109.         }
  110.  
  111.         puts("Entering Pass 2.\n\n");
  112.     }
  113.     }
  114.  
  115.     linptr = linbuf;  *linptr++ = '\n';    /*  List number of errors.    */
  116.     if (errcount == 0) strcpy(linptr,"No");
  117.     else { putdec(errcount,&linptr);  *linptr = '\0'; }
  118.     strcat(linbuf," error(s).\n");  puts(linbuf);  putchar('\n');
  119.     if (list != CONO && list != NOFILE) {
  120.     fputs(linbuf,list);  putc('\f',list);
  121.     }
  122.     if (list != NOFILE) {    /*  If needed, sort and list symbols.    */
  123.     n = sortsym();  sympoint = symtbl;
  124.     while (n > 0) {
  125.         linptr = linbuf;
  126.         for (m = 0; m < 4; m++) {
  127.         movmem(sympoint->symname,linptr,SYMLEN);
  128.         linptr += 8;  *linptr++ = ' ';  *linptr++ = ' ';
  129.         puthex4(sympoint->symvalu,&linptr);  *linptr++ = ' ';
  130.         *linptr++ = ' ';  *linptr++ = ' ';  *linptr++ = ' ';
  131.         sympoint++;
  132.         if (--n <= 0) break;
  133.         }
  134.         linptr -= 4;  *linptr++ = '\n';  *linptr = '\0';
  135.         fputs(linbuf,list);
  136.     }
  137.     if (list >= LODISK) putc(CPMEOF,list);
  138.     else if (list == LST) putc('\f',list);
  139.     }
  140.     fflush(list);  fclose(list);
  141.  
  142.     fclose(source);  wipeout("\n");
  143. }
  144.  
  145. /*
  146. Function to set up the file structure.  Routine is called with
  147. the original argc and argv from main().
  148. */
  149.  
  150. setfiles(argc,argv)
  151. int argc;
  152. char *argv[];
  153. {
  154.     char c, *tptr, sorfname[16],lstfname[16],hexfname[16];
  155.  
  156.     if (!--argc) wipeout("\nNo file info supplied.\n");
  157.     source = list = hex = NOFILE;
  158.  
  159.     sorfname[0] = curdrive + 'A';  sorfname[1] = ':';  tptr = &sorfname[2];
  160.     for (++argv; (c = *(*argv)++) && c != '.'; *tptr++ = c);
  161.     *tptr = '\0';
  162.  
  163.     strcpy(lstfname,sorfname);  strcpy(hexfname,lstfname);
  164.     strcat(sorfname,".RCA");  strcat(lstfname,".PRN");
  165.     strcat(hexfname,".HEX");
  166.     if (!--argc) goto defsorf;
  167.  
  168.     for (++argv; **argv; ) {
  169.     switch (*(*argv)++) {
  170.         case 'S':    switch (c = *(*argv)++) {
  171.                 case 'A':
  172.                 case 'B':
  173.                 case 'C':
  174.                 case 'D':    sorfname[0] = c;
  175.  
  176.                 case '-':    if (fopen(sorfname,source = &_source)
  177.                         != ERROR) break;
  178.                     wipeout("\nCan't open source.\n");
  179.  
  180.                 default:    goto badcomnd;
  181.             }
  182.             break;
  183.  
  184.         case 'L':    switch (c = *(*argv)++) {
  185.                 case 'A':
  186.                 case 'B':
  187.                 case 'C':
  188.                 case 'D':    lstfname[0] = c;
  189.  
  190.                 case '-':    if (fcreat(lstfname,list = &_list)
  191.                         != ERROR) break;
  192.                     wipeout("\nCan't open list.\n");
  193.  
  194.                 case 'X':    list = CONO;  break;
  195.  
  196.                 case 'Y':    list = LST;  break;
  197.  
  198.                 default:    goto badcomnd;
  199.             }
  200.             break;
  201.  
  202.         case 'H':    switch(c = *(*argv)++) {
  203.                 case 'A':
  204.                 case 'B':
  205.                 case 'C':
  206.                 case 'D':    hexfname[0] = c;
  207.  
  208.                 case '-':    if (fcreat(hexfname,hex = &_hex)
  209.                         != ERROR) break;
  210.                     wipeout("\nCan't open hex.\n");
  211.  
  212.                 case 'X':    hex = CONO;  break;
  213.  
  214.                 case 'Y':    hex = LST;  break;
  215.  
  216.                 default:    goto badcomnd;
  217.             }
  218.             break;
  219.  
  220.         badcomnd:
  221.         default:    wipeout("\nIllegal command line.\n");
  222.     }
  223.     }
  224.     if (source != NOFILE) return;
  225.  
  226.     defsorf:
  227.  
  228.     if (fopen(sorfname,&_source) == -1) wipeout("\nCan't open source.\n");
  229.     source = &_source;
  230. }
  231.         }
  232.             break;
  233.  
  234.         case 'L':    switch (c = *(*argv)++) {
  235.                 case 'A':
  236.                 ca